﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using GogTasks.UserControls;
using Business.Entities;
namespace GogTasks
{
    public partial class EditForm : Form
    {
        Task _taskEdit;
        Task _taskOrig;

        bool _systemUpdating = true;
        public event TaskEventHandler TaskUpdated;

        public EditForm()
        {
            _systemUpdating = true;
            InitializeComponent();
            Util.FixControlHiddenByInputPanel(Keyboard, MainPanel, NotesTextBox);
            SetFontSize();
            //DueCalendar.BringToFront();
            Activated += new EventHandler(EditForm_Activated);
        }
        #region Business methods

        private void SetFontSize()
        {
            Font font = null;
            // Set font size
            if (MobileContext.Config == null) return;
            if (MobileContext.Config.FontSize == FontSizeEnum.Small)
            {
                font = MobileContext.TextFontSmall;
            }
            else if (MobileContext.Config.FontSize == FontSizeEnum.Medium)
            {
                font = MobileContext.TextFontMedium;
            }
            else //(MobileContext.Config.FontSize == FontSizeEnum.Large)
            {
                font = MobileContext.TextFontLarge;
            }
            NameTextBox.Font = font;
            DueCheckBox.Font = font;
            DateTimePicker.Font = font;
            NotesTextBox.Font = font;
            NotesLabel.Font = font;
        }

        public new void Show()
        {
            base.Show();
            DueCheckBox.Focus();

            _systemUpdating = false;
        }

        public void EditTask(Task task)
        {
            _taskOrig = task;
            _taskEdit = task.Clone();
            DateTimePicker.Enabled = _taskEdit.HasTaskDate;
            BindUI();
            Show();
        }

        internal void NewTask(Task task)
        {
            SetFontSize();
            EditTask(task);
            NameTextBox.Focus();
        }

        private void BindUI()
        {
            taskBindingSource.DataSource = _taskEdit;
            var notes = _taskEdit.notes;
            notes = CleanupLinefeeds(notes);
            NotesTextBox.Text = notes;
        }

        private string CleanupLinefeeds(string notes)
        {
            if (notes == null) return null;
            notes = notes.Replace("\n\r", "\r\n");

            // Replace '\n' with '\r\n', but don't generate duplicate '\r's
            try
            {
                var list = new List<int>();
                for (int i = 1; i < notes.Length; i++)
                {
                    if (notes[i] == '\n' && notes[i - 1] != '\r') list.Insert(0, i);
                }
                foreach (int index in list)
                {
                    notes = notes.Substring(0, index) + '\r' + notes.Substring(index);
                }
            }
            catch (Exception)
            {
                notes = _taskEdit.notes.Replace("\n\r", "\r\n");
            }
            return notes;
        }

        private void Done()
        {
            if (_taskEdit == null) return;
            Commit();
            //DueCheckBox.Focus(); // Just to commit any text box changes
            if (!_taskEdit.DataEquals(_taskOrig))
            {
                _taskOrig.CopyProperties(_taskEdit, false);
                _taskOrig.LastModified = DateTime.Now;
                if (TaskUpdated != null) TaskUpdated.Invoke(this, new TaskEventArgs { Task = _taskOrig });
            }
            Keyboard.Enabled = false;
            Hide();
        }

        private void Commit()
        {
            // Basically, databinding doesn't work
            _taskEdit.name = NameTextBox.Text;
            _taskEdit.notes = NotesTextBox.Text;
            if (DueCheckBox.Checked)
            {
                _taskEdit.TaskDate = DateTimePicker.Value;
            }
            else _taskEdit.TaskDate = DateTime.MinValue;
        }
        #endregion
        #region Event Listeners
        void EditForm_Activated(object sender, EventArgs e)
        {
        }

        private void DoneButton_Click(object sender, EventArgs e)
        {
            Done();
        }


        private void CancelButton_Click(object sender, EventArgs e)
        {
            Keyboard.Enabled = false;
            Hide();
        }

        private void NameTextBox_GotFocus(object sender, EventArgs e)
        {
            if (!_systemUpdating) Keyboard.Enabled = true;
            var len = NameTextBox.Text.Length;
            NameTextBox.SelectionStart = len;
            NameTextBox.SelectionLength = 0;
        }

        private void NotesTextBox_GotFocus(object sender, EventArgs e)
        {
            if (!_systemUpdating) Keyboard.Enabled = true;
        }

        private void DueCheckBox_CheckStateChanged(object sender, EventArgs e)
        {
        }

        private void Keyboard_EnabledChanged(object sender, EventArgs e)
        {

        }

        private void DueCheckBox_Click(object sender, EventArgs e)
        {

            DateTimePicker.Enabled = DueCheckBox.Checked; 
            // Databinding SHOULD have taken care of this: 
            _taskEdit.HasTaskDate = DueCheckBox.Checked; 
        }

        private void taskBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
        }

        private void EditForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Done();
        }

        private void EditForm_Deactivate(object sender, EventArgs e)
        {

        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            _taskEdit.TaskDate = DateTimePicker.Value;
        }

        #endregion
    }
    public delegate void TaskEventHandler(object sender, TaskEventArgs args);

    public class TaskEventArgs :EventArgs
    {
        public Task Task;
    }
}